| @@ -238,6 +238,8 @@ urlpatterns += [ | ||
| 238 | 238 | url(r'^tj/distributor$', tj_views.tj_distributor, name='tj_distributor'), # 统计数据(经销商维度) | 
| 239 | 239 | url(r'^tj/consumer$', tj_views.tj_consumer, name='tj_consumer'), # 统计数据(消费者维度) | 
| 240 | 240 | url(r'^tj/generate$', tj_views.tj_generate, name='tj_generate'), # 统计数据生成 | 
| 241 | + | |
| 242 | + url(r'^v2/tj$', tj_views.v2_tj_distributor, name='v2_tj_distributor'), # 统计数据 | |
| 241 | 243 | ] | 
| 242 | 244 |  | 
| 243 | 245 | urlpatterns += [ | 
| @@ -0,0 +1,35 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +# Generated by Django 1.11.15 on 2018-10-11 05:26 | |
| 3 | +from __future__ import unicode_literals | |
| 4 | + | |
| 5 | +from django.db import migrations, models | |
| 6 | + | |
| 7 | + | |
| 8 | +class Migration(migrations.Migration): | |
| 9 | + | |
| 10 | + dependencies = [ | |
| 11 | +        ('statistic', '0008_auto_20181007_0322'), | |
| 12 | + ] | |
| 13 | + | |
| 14 | + operations = [ | |
| 15 | + migrations.CreateModel( | |
| 16 | + name='SaleclerkSaleStatisticInfo', | |
| 17 | + fields=[ | |
| 18 | +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
| 19 | +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')), | |
| 20 | +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), | |
| 21 | +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), | |
| 22 | +                ('brand_id', models.CharField(blank=True, db_index=True, help_text='\u54c1\u724c\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='brand_id')), | |
| 23 | +                ('distributor_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='distributor_id')), | |
| 24 | +                ('distributor_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='distributor_name')), | |
| 25 | +                ('clerk_id', models.CharField(blank=True, db_index=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='clerk_id')), | |
| 26 | +                ('clerk_name', models.CharField(blank=True, help_text='\u5e97\u5458\u540d\u79f0', max_length=32, null=True, verbose_name='clerk_name')), | |
| 27 | +                ('ymd', models.IntegerField(db_index=True, default=0, help_text='\u5e74\u6708\u65e5', verbose_name='ymd')), | |
| 28 | +                ('num', models.IntegerField(default=0, help_text='\u6570\u91cf', verbose_name='num')), | |
| 29 | + ], | |
| 30 | +            options={ | |
| 31 | + 'verbose_name': '[\u7ecf\u9500\u5546\u7ef4\u5ea6]\u9500\u552e\u5458\u9500\u91cf\u7edf\u8ba1', | |
| 32 | + 'verbose_name_plural': '[\u7ecf\u9500\u5546\u7ef4\u5ea6]\u9500\u552e\u5458\u9500\u91cf\u7edf\u8ba1', | |
| 33 | + }, | |
| 34 | + ), | |
| 35 | + ] | 
| @@ -129,7 +129,34 @@ class ProvinceSaleStatisticInfo(BaseModelMixin): | ||
| 129 | 129 |          return { | 
| 130 | 130 | 'province_code': self.province_code, | 
| 131 | 131 | 'province_name': self.province_name, | 
| 132 | - 'ymd': self.ymd, | |
| 132 | + # 'ymd': self.ymd, | |
| 133 | + 'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, | |
| 134 | + } | |
| 135 | + | |
| 136 | + | |
| 137 | +class SaleclerkSaleStatisticInfo(BaseModelMixin): | |
| 138 | + brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) | |
| 139 | + distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) | |
| 140 | + distributor_name = models.CharField(_(u'distributor_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称') | |
| 141 | + clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) | |
| 142 | + clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'店员名称') | |
| 143 | + ymd = models.IntegerField(_(u'ymd'), default=0, help_text=u'年月日', db_index=True) # 例:20171208, tc.local_string(format='%Y%m%d'), 0 为全部 | |
| 144 | + num = models.IntegerField(_(u'num'), default=0, help_text=u'数量') | |
| 145 | + | |
| 146 | + class Meta: | |
| 147 | + verbose_name = _(u'[经销商维度]销售员销量统计') | |
| 148 | + verbose_name_plural = _(u'[经销商维度]销售员销量统计') | |
| 149 | + | |
| 150 | + def __unicode__(self): | |
| 151 | + return unicode(self.pk) | |
| 152 | + | |
| 153 | + @property | |
| 154 | + def data(self): | |
| 155 | +        return { | |
| 156 | + 'distributor_name': self.distributor_name, | |
| 157 | + 'salesman_id': self.clerk_id, | |
| 158 | + 'salesman_name': self.clerk_name, | |
| 159 | + # 'ymd': self.ymd, | |
| 133 | 160 | 'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, | 
| 134 | 161 | } | 
| 135 | 162 |  | 
| @@ -176,7 +203,7 @@ class ConsumeModelSaleStatisticInfo(BaseModelMixin): | ||
| 176 | 203 |          return { | 
| 177 | 204 | 'model_id': self.model_id, | 
| 178 | 205 | 'model_name': self.model_name, | 
| 179 | - 'ymd': self.ymd, | |
| 206 | + # 'ymd': self.ymd, | |
| 180 | 207 | 'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, | 
| 181 | 208 | } | 
| 182 | 209 |  | 
| @@ -11,7 +11,7 @@ from mch.models import BrandInfo, DistributorInfo, ModelInfo | ||
| 11 | 11 | from statistic.models import (ConsumeDistributorSaleStatisticInfo, ConsumeModelSaleStatisticInfo, | 
| 12 | 12 | ConsumeProvinceSaleStatisticInfo, ConsumeSaleStatisticInfo, DistributorSaleStatisticInfo, | 
| 13 | 13 | ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, RegisterStatisticInfo, | 
| 14 | - SaleStatisticInfo) | |
| 14 | + SaleclerkSaleStatisticInfo, SaleStatisticInfo) | |
| 15 | 15 | from utils.rdm_utils import randnum | 
| 16 | 16 |  | 
| 17 | 17 |  | 
| @@ -202,3 +202,78 @@ def __tj_generate(ymd=None): | ||
| 202 | 202 | brand_id=brand.brand_id, | 
| 203 | 203 | ymd=ymd, | 
| 204 | 204 | ) | 
| 205 | + | |
| 206 | + | |
| 207 | +def ymdtj(brand_id, ymd, lastymd): | |
| 208 | + # 周期内扫描用户人数 | |
| 209 | + try: | |
| 210 | + scan_user_count = ConsumeSaleStatisticInfo.objects.get(brand_id=brand_id, ymd=ymd).num | |
| 211 | + except ConsumeSaleStatisticInfo.DoesNotExist: | |
| 212 | + scan_user_count = 0 | |
| 213 | + | |
| 214 | + try: | |
| 215 | + last_scan_user_count = ConsumeSaleStatisticInfo.objects.get(brand_id=brand_id, ymd=lastymd).num | |
| 216 | + except ConsumeSaleStatisticInfo.DoesNotExist: | |
| 217 | + last_scan_user_count = 0 | |
| 218 | + | |
| 219 | + # 与上个统计周期数据的用户人数比例 | |
| 220 | + user_count_increase_pct = '%.2f' % scan_user_count * 100.0 / last_scan_user_count if last_scan_user_count != 0 else 0 | |
| 221 | + | |
| 222 | + # 周期内镜头销售支数 | |
| 223 | + try: | |
| 224 | + sell_volume_count = SaleStatisticInfo.objects.get(brand_id=brand_id, ymd=ymd).num | |
| 225 | + except SaleStatisticInfo.DoesNotExist: | |
| 226 | + sell_volume_count = 0 | |
| 227 | + | |
| 228 | + try: | |
| 229 | + last_sell_volume_count = SaleStatisticInfo.objects.get(brand_id=brand_id, ymd=lastymd).num | |
| 230 | + except SaleStatisticInfo.DoesNotExist: | |
| 231 | + last_sell_volume_count = 0 | |
| 232 | + | |
| 233 | + # 与上个统计周期数据的销售支数比例 | |
| 234 | + volume_count_increase_pct = '%.2f' % sell_volume_count * 100.0 / last_sell_volume_count if last_sell_volume_count != 0 else 0 | |
| 235 | + | |
| 236 | + # 统计周期内型号扫描排行数据,请按顺序返回 | |
| 237 | +    models = ConsumeModelSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('-num') | |
| 238 | + models = [m.data for m in models] | |
| 239 | + | |
| 240 | + # 统计周期内销售员排行数据,请按顺序返回 | |
| 241 | +    salesmen = SaleclerkSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('-num') | |
| 242 | + salesmen = [s.data for s in salesmen] | |
| 243 | + | |
| 244 | + # 统计周期内省份销量排行数据,请按顺序返回 | |
| 245 | +    provinces = ProvinceSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('position') | |
| 246 | + provinces = [p.data for p in provinces] | |
| 247 | + | |
| 248 | +    return { | |
| 249 | + 'scan_user_count': scan_user_count, | |
| 250 | + 'sell_volume_count': sell_volume_count, | |
| 251 | + 'user_count_increase_pct': user_count_increase_pct, | |
| 252 | + 'volume_count_increase_pct': volume_count_increase_pct, | |
| 253 | + 'models': models, | |
| 254 | + 'salesmen': salesmen, | |
| 255 | + 'provinces': provinces, | |
| 256 | + } | |
| 257 | + | |
| 258 | + | |
| 259 | +@logit | |
| 260 | +def v2_tj_distributor(request): | |
| 261 | +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) | |
| 262 | + | |
| 263 | + year = tc.local_string(format='%Y') | |
| 264 | + month = tc.local_string(format='%Y%m') | |
| 265 | + day = tc.local_string(format='%Y%m%d') | |
| 266 | + | |
| 267 | + lastyear = tc.local_string(tc.several_time_ago(years=1), format='%Y') | |
| 268 | + lastmonth = tc.local_string(tc.several_time_ago(months=1), format='%Y%m') | |
| 269 | + lastday = tc.local_string(tc.several_time_ago(days=1), format='%Y%m%d') | |
| 270 | + | |
| 271 | + year_data = ymdtj(brand_id, year, lastyear) | |
| 272 | + month_data = ymdtj(brand_id, month, lastmonth) | |
| 273 | + day_data = ymdtj(brand_id, day, lastday) | |
| 274 | + | |
| 275 | +    return response(200, 'Get TJ Data Success', u'获取统计数据成功', data={ | |
| 276 | + 'year_data': year_data, | |
| 277 | + 'month_data': month_data, | |
| 278 | + 'day_data': day_data, | |
| 279 | + }) |